/****************************************************************************
    Kantaoke, a karaoke game made with BennuGD.
    Copyright (C) 2010 Joseba García Echebarria

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/

#ifndef __MENU_INC__
#define __MENU_INC__

// Pretty much like rotate_cover function in inc/playback.inc, but
// plays a bit more with the background images (moves them, etc..)
Process menu_rotate_cover(song kar, int delay)
Begin
	// Do nothing for now, as the old menu_rotate_cover crashed miserably :(
End;

// This process controls the main menu, and its movement.
Process menu()
Private
  int procid=0, i=0, j=0, announcer_pid=0, songid=0;
  int carrousel_pid1=0, carrousel_pid2=0, carrousel_pid3=0;
  int carrousel_theta=0, vtheta=4000, carrousel_moving=0;
  song song_preview;
  
Begin
  // In case there was any other process running, kill'em
  let_me_alone();

  // Create the processes needed for the carrousel
  carrousel_pid1 = robot();
  carrousel_pid2 = robot();
  carrousel_pid3 = robot();
  
  // Place the elements on the carrousel
  // carrousel_pid1.aux defines the offset angle
  carrousel_pid1.aux =  60000.0;
  carrousel_pid3.aux = -60000.0;
  carrousel_pid2.aux =      0.0;

  carrousel_pid1.x = resx/2+resx*sin(carrousel_theta+carrousel_pid1.aux)/3.5;
  carrousel_pid1.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid1.aux);
  carrousel_pid1.z = 0;
  carrousel_pid1.size = 100-abs(carrousel_theta+carrousel_pid1.aux)/1000.0;
  carrousel_pid1.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid1.aux)/90000.0);
  carrousel_pid1.graph = songs[1].cover;
  carrousel_pid3.x = resx/2+resx*sin(carrousel_theta+carrousel_pid3.aux)/3.5;
  carrousel_pid3.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid3.aux);
  carrousel_pid3.z = 0;
  carrousel_pid3.size = 100-abs(carrousel_theta+carrousel_pid3.aux)/1000.0;
  carrousel_pid3.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid3.aux)/90000.0);
  carrousel_pid3.graph = songs[songs_found-1].cover;
  carrousel_pid2.x = resx/2+resx*sin(carrousel_theta+carrousel_pid2.aux)/3.5;;
  carrousel_pid2.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid2.aux);
  carrousel_pid2.z = -1;
  carrousel_pid2.size = 100-abs(carrousel_theta+carrousel_pid2.aux)/1000.0;
  carrousel_pid2.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid2.aux)/90000.0);
  carrousel_pid2.graph = songs[0].cover;
  
  // Make the covers change in the background, and play it
  song_preview.coverpath = songs[i].bgpath;
  song_preview.bgpath = songs[i].coverpath;
  if(exists(announcer_pid))
    announcer_pid.die = 1;
    FRAME;      // We allow the background song announcer to die gracefully
  End;
  announcer_pid = menu_rotate_cover(song_preview, 600);
  songid = _load_song(songs[i].music_file);
  _play_song(songid, 0);
  dbg_print("Menu set up and waiting for orders");

  timer[9] = 0;
  LOOP
    // This code handles carrousel movement
    if(carrousel_moving != 0)
      if(abs(carrousel_theta) < 60000)
        carrousel_theta += carrousel_moving*vtheta;

        carrousel_pid1.x = resx/2+resx*sin(carrousel_theta+carrousel_pid1.aux)/3.5;
        carrousel_pid1.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid1.aux);
        carrousel_pid1.size = 100-abs(carrousel_theta+carrousel_pid1.aux)/1000.0;
        carrousel_pid1.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid1.aux)/90000.0);
        carrousel_pid3.x = resx/2+resx*sin(carrousel_theta+carrousel_pid3.aux)/3.5;
        carrousel_pid3.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid3.aux);
        carrousel_pid3.size = 100-abs(carrousel_theta+carrousel_pid3.aux)/1000.0;
        carrousel_pid3.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid3.aux)/90000.0);
        carrousel_pid2.x = resx/2+resx*sin(carrousel_theta+carrousel_pid2.aux)/3.5;;
        carrousel_pid2.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid2.aux);
        carrousel_pid2.size = 100-abs(carrousel_theta+carrousel_pid2.aux)/1000.0;
        carrousel_pid2.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid2.aux)/90000.0);

        // Change the z of the covers, when they cross their ways
        if( (carrousel_pid2.size < carrousel_pid1.size) && carrousel_moving < 0)
          carrousel_pid2.z = 0;
          carrousel_pid1.z = -1;
        end;
        
        if((carrousel_pid2.size < carrousel_pid3.size) && carrousel_moving > 0)
          carrousel_pid2.z = 0;
          carrousel_pid3.z = -1;
        end;

        // Check if we must replace the cover (because it became so small
        // that it's no longer visible) and then place the next one on the other
        // side of the carrousel
        if(carrousel_pid3.size <= 15)
          carrousel_pid3.aux = 120000.0;
          carrousel_pid3.graph = songs[i+1].cover;
        end;

        if(carrousel_pid1.size <= 15)
          carrousel_pid1.aux = -120000.0;
          carrousel_pid1.graph = songs[i-1].cover;
        end;
      else
        // The carrousel was moving, but must now stop as it's reached the end
        // We switch the process graphics and move the process back to their
        // place (i.e. carrousel_pid2 is the one in the center, always)
        carrousel_theta = 0.0;
        carrousel_pid1.aux =  60000.0;
        carrousel_pid3.aux = -60000.0;
        carrousel_pid2.aux =      0.0;

        carrousel_pid1.x = resx/2+resx*sin(carrousel_theta+carrousel_pid1.aux)/3.5;
        carrousel_pid1.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid1.aux);
        carrousel_pid1.z = 0;
        carrousel_pid1.size = 100-abs(carrousel_theta+carrousel_pid1.aux)/1000.0;
        carrousel_pid1.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid1.aux)/90000.0);
        if(i > songs_found-2)
          carrousel_pid1.graph = songs[0].cover;
        else
          carrousel_pid1.graph = songs[i+1].cover;
        end;
        carrousel_pid3.x = resx/2+resx*sin(carrousel_theta+carrousel_pid3.aux)/3.5;
        carrousel_pid3.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid3.aux);
        carrousel_pid3.z = 0;
        carrousel_pid3.size = 100-abs(carrousel_theta+carrousel_pid3.aux)/1000.0;
        carrousel_pid3.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid3.aux)/90000.0);
        if(i > 0)
          carrousel_pid3.graph = songs[i-1].cover;
        else
          carrousel_pid3.graph = songs[songs_found-1].cover;
        end;
        carrousel_pid2.x = resx/2+resx*sin(carrousel_theta+carrousel_pid2.aux)/3.5;;
        carrousel_pid2.y = resy/2+50.0*cos(carrousel_theta+carrousel_pid2.aux);
        carrousel_pid2.z = -1;
        carrousel_pid2.size = 100-abs(carrousel_theta+carrousel_pid2.aux)/1000.0;
        carrousel_pid2.alpha = 255*(1.0-0.4*abs(carrousel_theta+carrousel_pid2.aux)/90000.0);
        carrousel_pid2.graph = songs[i].cover;

        // Make the covers change in the background, and play it
        song_preview.coverpath = songs[i].bgpath;
        song_preview.bgpath = songs[i].coverpath;
        if(exists(announcer_pid))
          announcer_pid.die = 1;
		  announcer_pid = 0;
          FRAME;      // We allow the background song announcer to die gracefully
        End;
        announcer_pid = menu_rotate_cover(song_preview, 600);
        // If music is being played, stop it
        if(_is_playing_song(songid))
          _stop_song(songid);
          songid=0;
        end;
        // Check the music file exists, otherwise try converting it to UTF8
        songid=_load_song(songs[i].music_file);
        _play_song(songid, 0);
		
		// I'm now ready to accept more input
		carrousel_moving = 0;
      end;
    end;

    // Handle key input
    if( (key(_right) || mouse.wheelup || mouse.right) && carrousel_moving == 0)
      i++;
      if(i >= songs_found)
        i=0;
      end;
      
      // Put the cover on the right on the bottom
      carrousel_pid1.z++;
      carrousel_moving = -1;
    end;
    
    if( (key(_left) || mouse.wheeldown) &&  carrousel_moving == 0)
      i--;
      if(i < 0)
        i=songs_found-1;
      end;
      
      // Put the cover on the left on the bottom
      carrousel_pid3.z++;
      carrousel_moving = 1;
    end;
    
    // Start playing the song
    if( (key(_enter) || mouse.left) && carrousel_moving == 0)
      //Fade off
      fade(0, 0, 0, 15);
      while(fading)
        FRAME;
      end;

      // Tell the carrousel to die
      if(exists(carrousel_pid1))
        carrousel_pid1.die = 1;
      end;
      if(exists(carrousel_pid2))
        carrousel_pid2.die = 1;
      end;
      if(exists(carrousel_pid3))
        carrousel_pid3.die = 1;
      end;
      FRAME;

      // Tell the announcer to die, if still on screen
      if(exists(announcer_pid))
        announcer_pid.die = 1;
		announcer_pid=0;
      end;
      
      // If music is being played, stop it
      if(_is_playing_song(songid))
        _stop_song(songid);
      end;
      
      // Start the process that will play the song
      procid = play_file(songs[i].dirname, songs[i].filename);
      if(procid == -1)		// Failed, create a new menu and quit :(
        dbg_print("Couldn't play specified file, aborting!");
        let_me_alone();
        //Fade back on to the new menu, then die
        fade(100, 100, 100, 15);
        while(fading)
          FRAME;
        end;
        menu();
        return -1;
      end;
      
      //Fade back on to the song
      fade(100, 100, 100, 15);
      while(fading)
        FRAME;
      end;

      return 0;     //Play_file should create a new menu for us
    end;
    
    // Quit from the menu
    if(key(_esc) && carrousel_moving == 0)
      //Fade off
      fade(0, 0, 0, 15);
      while(fading)
        FRAME;
      end;
      
      // Tell the carrousel to die
      if(exists(carrousel_pid1))
        carrousel_pid1.die = 1;
      end;
      if(exists(carrousel_pid2))
        carrousel_pid2.die = 1;
      end;
      if(exists(carrousel_pid3))
        carrousel_pid3.die = 1;
      end;
      FRAME;    // This way, they'll die gracefully
      
      // Unload all the cover art
      for(i=0; i < MAX_ALLOWED_SONGS; i++)
        if(songs[i].cover != 0)
          unload_map(0, songs[i].cover);
        end;
      end;
      
      exit();
    end;
    FRAME;
  end;
End;

// This process implements the menu used when no songs is found
Process no_songs_menu()
Private
  int pid1=0, pid2=0, pid2_graph_noglow=0, pid2_graph_glow=0, aux_x=0, aux_y=0;
  string songsdir="", default_filebrowser="";

Begin
  // Clear the screen to delete all the written texts
  clear_screen();

  // Display the error
  pid1 = robot();
  pid1.graph = load_image(datadir+"img/no_songs_found.png");
  pid1.x = resx/2; pid1.y = resy/2; pid1.z = 255;
  resize_fullscreen(pid1);
  
  //Show the link to the songs folder, place it correctly onscreen
  pid2 = robot();
  pid2.graph = pid2_graph_noglow = load_image(datadir+"img/songs_folder_noglow.png");
  pid2_graph_glow = load_image(datadir+"img/songs_folder_glow.png");
  pid2.size = pid1.size;
  aux_x = graphic_info(0, pid1.graph, G_WIDTH);
  aux_y = graphic_info(0, pid1.graph, G_HEIGHT);
  pid2.x = pid1.x-0.36*aux_x*(pid1.size/100.0);
  pid2.y = pid1.y+0.25*aux_y*(pid1.size/100.0);
  
  // We'll use the width & height of pid2 to compute collisions with the mouse
  aux_x = graphic_info(0, pid2.graph, G_WIDTH);
  aux_y = graphic_info(0, pid2.graph, G_HEIGHT);
  
  // Enable the mouse
  mouse_controller();
  
  while( die == 0 )
    if( key(_enter) || key(_esc) || key(_space))
      die = 1;
    end;

    // Check if we should change the graph for the link
    if( mouse.x >= (pid2.x-aux_x/2) && mouse.x <= (pid2.x+aux_x/2) &&
        mouse.y >= (pid2.y-aux_y/2) && mouse.y <= (pid2.y+aux_y/2) )
        
        // If the user clicked the mouse, show the songs folder, then quit.
        if(mouse.left)
		  if(OS_ID == OS_MACOS)
			songsdir = getenv("HOME") + "/Library/" + gamename + "/Songs/";
			default_filebrowser = "open";
		  elif(OS_ID == OS_LINUX)
		    songsdir = getenv("HOME") + "/." + gamename + "/Songs/";
		    default_filebrowser = "xdg-open";
		  elif(OS_ID == OS_WIN32)
		    songsdir = getenv("APPDATA") + "\" + gamename + "\Songs\";
			default_filebrowser = "explorer";
		  else
            songsdir = datadir + "/Songs/";
          end
          say("Opening songs dir: "+songsdir);
          create_dir_hierarchy(songsdir);
          exec(_P_NOWAIT, default_filebrowser, 1, &songsdir);
          die = 1;
        end;
        
        pid2.graph = pid2_graph_glow;
    else
      pid2.graph = pid2_graph_noglow;
    end;
    FRAME;
  end;

  //Unload the graph of the robot, tell it to die
  unload_map(0, pid1.graph);
  pid1.graph=0;
  pid1.die=1;
  
  pid2.graph = 0;
  pid2.die = 1;
  unload_map(0, pid2_graph_glow); unload_map(0, pid2_graph_noglow);
  
  //Now quit
  exit();
End;

#endif
